package io.github.echarts.model.theme.provider;

import io.github.echarts.model.context.ConfigurationContext;
import io.github.echarts.model.theme.AbstractDefaultValueProvider;
import io.github.echarts.model.theme.Theme;
import io.github.echarts.option.component.Legend;
import io.github.echarts.option.style.TextStyle;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 图例默认值提供者
 * <p>
 * 为图例组件提供默认配置，包括位置、样式等设置。
 * </p>
 */
public class LegendDefaultValueProvider extends AbstractDefaultValueProvider<Legend> {
    
    /**
     * 构造函数
     */
    public LegendDefaultValueProvider() {
        super(Legend.class);
    }
    
    @Override
    protected void initDefaultValues() {
        // 基本属性
        registerDefaultValue("show", true);
        registerDefaultValue("left", "center");
        registerDefaultValue("top", "top");
        registerDefaultValue("orient", "horizontal");
        registerDefaultValue("align", "auto");
        registerDefaultValue("padding", 5);
        registerDefaultValue("itemGap", 10);
        registerDefaultValue("itemWidth", 25);
        registerDefaultValue("itemHeight", 14);
        registerDefaultValue("selectedMode", true);
    }
    
    @Override
    public void applyDefaults(Legend legend, ConfigurationContext context) {
        super.applyDefaults(legend, context);
        
        // 设置默认文本样式
        if (legend.getTextStyle() == null) {
            TextStyle textStyle = new TextStyle();
            textStyle.setFontSize(12);
            legend.setTextStyle(textStyle);
        }
        
        // 设置默认图标类型
        if (legend.getIcon() == null) {
            legend.setIcon("rect");
        }
        
        // 如果是极坐标或饼图，默认放在右侧
        Boolean isPolarOrPie = isPolarOrPieChart(context);
        if (Boolean.TRUE.equals(isPolarOrPie)) {
            if (legend.getLeft() == null || "center".equals(legend.getLeft())) {
                legend.setLeft("right");
            }
            if (legend.getOrient() == null || "horizontal".equals(legend.getOrient())) {
                legend.setOrient("vertical");
            }
        }
    }
    
    @Override
    protected void applyDataDrivenDefaults(Legend legend, ConfigurationContext context) {
        // 检查系列数量，调整布局
        Integer seriesCount = getSeriesCount(context);
        if (seriesCount != null && seriesCount > 6) {
            // 系列较多时，建议使用水平图例
            if (legend.getOrient() == null) {
                legend.setOrient("horizontal");
            }
            
            // 系列非常多时，可能需要调整为滚动图例
            if (seriesCount > 12) {
                legend.setType("scroll");
                legend.setWidth("80%");
                
                // 系列过多时，默认放在底部
                if (legend.getTop() == null || "top".equals(legend.getTop())) {
                    legend.setTop("bottom");
                }
            }
        }
        
        // 检查图例项文本长度，可能需要调整布局
        List<String> legendNames = getLegendNames(context);
        boolean hasLongNames = false;
        for (String name : legendNames) {
            if (name.length() > 10) {
                hasLongNames = true;
                break;
            }
        }
        
        // 如果有长图例项，建议使用垂直布局
        if (hasLongNames && legend.getOrient() == null) {
            legend.setOrient("vertical");
            
            // 默认放在右侧
            if (legend.getLeft() == null || "center".equals(legend.getLeft())) {
                legend.setLeft("right");
            }
        }
    }
    
    /**
     * 判断图表是否为极坐标或饼图
     * 
     * @param context 配置上下文
     * @return 是否为极坐标或饼图
     */
    private Boolean isPolarOrPieChart(ConfigurationContext context) {
        if (context == null) {
            return null;
        }
        
        // 检查图表类型
        Object chartTypeObj = context.get("chartType");
        if (chartTypeObj != null) {
            String chartType = chartTypeObj.toString().toLowerCase();
            return "pie".equals(chartType) || "radar".equals(chartType) || 
                   "polar".equals(chartType) || "gauge".equals(chartType);
        }
        
        // 检查是否有极坐标系
        Object hasPolarObj = context.get("hasPolarCoordinateSystem");
        if (hasPolarObj instanceof Boolean) {
            return (Boolean) hasPolarObj;
        }
        
        return null;
    }
    
    /**
     * 获取系列数量
     * 
     * @param context 配置上下文
     * @return 系列数量
     */
    private Integer getSeriesCount(ConfigurationContext context) {
        if (context == null) {
            return null;
        }
        
        Object seriesCountObj = context.get("seriesCount");
        if (seriesCountObj instanceof Integer) {
            return (Integer) seriesCountObj;
        } else if (seriesCountObj instanceof Number) {
            return ((Number) seriesCountObj).intValue();
        }
        
        return null;
    }
    
    /**
     * 获取系列名称列表
     * 
     * @param context 配置上下文
     * @return 系列名称列表
     */
    private List<String> getSeriesNames(ConfigurationContext context) {
        if (context == null) {
            return new ArrayList<>();
        }
        
        Object seriesNamesObj = context.get("seriesNames");
        if (seriesNamesObj instanceof List) {
            @SuppressWarnings("unchecked")
            List<String> seriesNames = (List<String>) seriesNamesObj;
            return new ArrayList<>(seriesNames);
        }
        
        return new ArrayList<>();
    }
    
    /**
     * 获取图例名称列表
     * 
     * @param context 配置上下文
     * @return 图例名称列表
     */
    private List<String> getLegendNames(ConfigurationContext context) {
        // 首先尝试从上下文中获取图例名称
        List<String> legendNames = getSeriesNames(context);
        if (!legendNames.isEmpty()) {
            return legendNames;
        }
        
        // 如果没有明确的图例名称，则返回空列表
        return new ArrayList<>();
    }
    
    /**
     * 检查图例数据是否为空
     * 
     * @param data 图例数据对象
     * @return 是否为空
     */
    private boolean isDataEmpty(Object data) {
        if (data == null) {
            return true;
        }
        
        // 检查数组类型
        if (data.getClass().isArray()) {
            return Array.getLength(data) == 0;
        }
        
        // 检查列表类型
        if (data instanceof List) {
            return ((List<?>) data).isEmpty();
        }
        
        return false;
    }
    
    @Override
    public void ensureCompleteness(Legend legend, ConfigurationContext context) {
        // 确保文本样式对象的完整性
        if (legend.getTextStyle() == null) {
            legend.setTextStyle(new TextStyle());
        }
        
        // 确保图例数据的存在
        if (isDataEmpty(legend.getData())) {
            // 尝试从上下文中获取系列名称
            List<String> seriesNames = getSeriesNames(context);
            if (!seriesNames.isEmpty()) {
                legend.setData(seriesNames);
            }
        }
    }
    
    @Override
    public void applyTheme(Legend legend, Theme theme) {
        if (legend == null || theme == null) {
            return;
        }
        
        // 应用文本样式
        if (legend.getTextStyle() != null) {
            TextStyle textStyle = legend.getTextStyle();
            TextStyle themeTextStyle = theme.getTextStyle();
            
            if (themeTextStyle != null) {
                // 只应用未设置的属性
                if (textStyle.getColor() == null) {
                    textStyle.setColor(themeTextStyle.getColor());
                }
                if (textStyle.getFontFamily() == null) {
                    textStyle.setFontFamily(themeTextStyle.getFontFamily());
                }
                if (textStyle.getFontSize() == null) {
                    // 图例字体通常比正常文本小一号
                    textStyle.setFontSize(Math.max(10, themeTextStyle.getFontSize() - 2));
                }
            }
        } else {
            TextStyle textStyle = new TextStyle();
            TextStyle themeTextStyle = theme.getTextStyle();
            
            if (themeTextStyle != null) {
                textStyle.setColor(themeTextStyle.getColor());
                textStyle.setFontFamily(themeTextStyle.getFontFamily());
                // 图例字体通常比正常文本小一号
                textStyle.setFontSize(Math.max(10, themeTextStyle.getFontSize() - 2));
            }
            
            legend.setTextStyle(textStyle);
        }
    }
} 